package com.biodiv.miracle.boot.core;

import com.fasterxml.jackson.core.JsonProcessingException;
import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;
import redis.clients.jedis.JedisPoolConfig;

import java.util.HashSet;
import java.util.Map;
import java.util.Set;

public class RedisTemplate {

    private final JedisPool jedisPool;

    // 构造函数，传入 Redis 连接参数
    public RedisTemplate(String host, int port, String password) {
        JedisPoolConfig poolConfig = new JedisPoolConfig();
        // 最大连接数
        poolConfig.setMaxTotal(100);
        // 最大空闲连接
        poolConfig.setMaxIdle(10);
        // 最小空闲连接
        poolConfig.setMinIdle(1);
        // 获取连接最大等待时间
        poolConfig.setMaxWaitMillis(3000);

        if (password == null || password.isEmpty()) {
            this.jedisPool = new JedisPool(poolConfig, host, port);
        } else {
            this.jedisPool = new JedisPool(poolConfig, host, port, 3000, password);
        }
    }

    // 获取 Jedis 实例
    private Jedis getJedis() {
        return jedisPool.getResource();
    }

    // 关闭资源池（在应用关闭时调用）
    public void shutdown() {
        jedisPool.close();
    }

    // =================== String 类型操作 ===================

    public void set(String key, String value) {
        try (Jedis jedis = getJedis()) {
            jedis.set(key, value);
        }
    }

    public String get(String key) {
        try (Jedis jedis = getJedis()) {
            return jedis.get(key);
        }
    }

    public void setex(String key, int seconds, String value) {
        try (Jedis jedis = getJedis()) {
            jedis.setex(key, seconds, value);
        }
    }

    public void del(String key) {
        try (Jedis jedis = getJedis()) {
            jedis.del(key);
        }
    }

    // =================== Hash 类型操作 ===================

    public void hset(String key, String field, String value) {
        try (Jedis jedis = getJedis()) {
            jedis.hset(key, field, value);
        }
    }

    public String hget(String key, String field) {
        try (Jedis jedis = getJedis()) {
            return jedis.hget(key, field);
        }
    }

    public Map<String, String> hgetAll(String key) {
        try (Jedis jedis = getJedis()) {
            return jedis.hgetAll(key);
        }
    }

    // =================== List 类型操作 ===================

    public void lpush(String key, String... values) {
        try (Jedis jedis = getJedis()) {
            jedis.lpush(key, values);
        }
    }

    public String lpop(String key) {
        try (Jedis jedis = getJedis()) {
            return jedis.lpop(key);
        }
    }

    // =================== Set 类型操作 ===================

    public void sadd(String key, String... members) {
        try (Jedis jedis = getJedis()) {
            jedis.sadd(key, members);
        }
    }

    public Set<String> smembers(String key) {
        try (Jedis jedis = getJedis()) {
            return jedis.smembers(key);
        }
    }

    // =================== ZSet 类型操作 ===================

    public void zadd(String key, double score, String member) {
        try (Jedis jedis = getJedis()) {
            jedis.zadd(key, score, member);
        }
    }

    public Set<String> zrange(String key, long start, long end) {
        try (Jedis jedis = getJedis()) {
            return new HashSet<>(jedis.zrange(key, start, end));
        }
    }

    // =================== 自定义序列化支持 ===================

    public void setObject(String key, Object value) throws JsonProcessingException {
        try (Jedis jedis = getJedis()) {
            String serialized = serialize(value);
            jedis.set(key, serialized);
        }
    }

    public <T> T getObject(String key, Class<T> clazz) throws JsonProcessingException {
        try (Jedis jedis = getJedis()) {
            String value = jedis.get(key);
            return deserialize(value, clazz);
        }
    }

    // 示例：使用 JSON 序列化（需引入 Jackson）
    private String serialize(Object obj) throws JsonProcessingException {
        return new com.fasterxml.jackson.databind.ObjectMapper().writeValueAsString(obj);
    }

    private <T> T deserialize(String json, Class<T> clazz) throws JsonProcessingException {
        return new com.fasterxml.jackson.databind.ObjectMapper().readValue(json, clazz);
    }
}